package com.反射Reflection.Reflection___;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ReflectionCreateNewInstance {
    /// ReflectionCreateNewInstance （反射创建新实例）
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        ///1. 传统方法
        System.out.println("===========传统方法创建对象===============");
        User user = new User();
        System.out.println(user);

        /// 加载User类的 Class类
        Class<?> userClass = Class.forName("com.反射Reflection.Reflection___.User");
        /// 2.反射调用无参public构造器
        System.out.println("\n\n======反射创建对象=============================");
        Constructor<?> constructor1 = userClass.getDeclaredConstructor();///得到无参构造器
        Object user1 = constructor1.newInstance();                       ///创建对象
        System.out.println(user1);

        System.out.println("\n\n======反射创建对象=============================");
        ///得到参数类型是String的构造器
        Constructor<?> constructor2 = userClass.getDeclaredConstructor(String.class);
        ///传入String 创建对象
        Object user2 = constructor2.newInstance("小狗");                     
        System.out.println(user2);

        System.out.println("\n\n======反射爆破 私有构造器 来创建对象=============================");
        ///得到参数类型是int，String的构造器
        Constructor<?> constructor3 = userClass.getDeclaredConstructor(int.class, String.class);
        ///因为是private，直接访问会报错，所以关闭访问安全检查（爆破）就可以访问
        constructor3.setAccessible(true);
        /// 用私有构造器创建对象
        Object user3 = constructor3.newInstance(20, "小鸟");
        System.out.println(user3);
    }
}


class User{
    private int age = 10;
    private String name = "猫猫";

    public User(){
        System.out.println("无参构造器被调用");
    }

    public User(String name){
        this.name = name;
        System.out.println("有参构造器User(String name)被调用");
    }

    private User(int age,String name){
        this.age = age;
        this.name = name;
        System.out.println("私有 有参构造器User(int age , String name)被调用");
    }

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}